#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
这个脚本用于将concepts.json文件转换为Markdown格式。
它支持处理多种内容类型，包括段落文本、列表、图片、代码示例等。
使用面向对象的方式实现，提高代码的可维护性和可扩展性。
"""

import json
import os
import sys
from typing import Dict, List, Any, Optional


class ContentProcessor:
    """内容处理器基类，定义内容处理的基本接口"""

    def process(self, content: Any) -> str:
        """处理内容的抽象方法

        Args:
            content: 要处理的内容

        Returns:
            str: 处理后的markdown文本
        """
        raise NotImplementedError("子类必须实现process方法")


class ParagraphProcessor(ContentProcessor):
    """段落处理器"""

    def __init__(self, formats: Optional[Dict] = None):
        """初始化段落处理器

        Args:
            formats: 包含链接和代码块信息的字典
        """
        self.formats = formats or {}

    def process(self, content: Dict) -> str:
        """处理段落内容，包括文本、代码块和链接

        Args:
            content: 段落内容字典，包含value、code_blocks和links属性

        Returns:
            str: 处理后的markdown文本
        """
        # 获取段落文本内容
        text = content.get('value', '')

        # 处理代码块
        code_blocks = content.get('code_blocks', [])
        if code_blocks:
            for code_block_id in code_blocks:
                # 从formats中获取代码块信息
                block_info = self.formats.get('code_blocks', {}).get(code_block_id, {})
                if block_info:
                    # 获取代码块中的文本
                    code_text = block_info.get('content', '').strip()
                    # 在原始文本中查找并替换为代码格式
                    if code_text in text:
                        text = text.replace(code_text, f"`{code_text}`")

        # 处理链接
        links = content.get('links', [])
        if links:
            for link_id in links:
                # 从formats中获取链接信息
                link_info = self.formats.get('links', {}).get(link_id, {})
                if link_info:
                    link_name = link_info.get('name', '')
                    link_href = link_info.get('href', '')
                    # 在原始文本中查找 name 并替换为 markdown 链接格式
                    if link_name and link_name in text:
                        text = text.replace(link_name, f"[{link_name}]({link_href})")
                    else:
                        # 如果找不到 name, 仍然尝试替换占位符
                        placeholder = f"<link>{link_id}</link>"
                        replacement = f"[{link_name}]({link_href})"
                        text = text.replace(placeholder, replacement)

        return f"{text}\n"


class ListProcessor(ContentProcessor):
    """列表处理器"""

    def process(self, content: Dict) -> str:
        result = []
        for item in content['items']:
            result.append(f"- {item['text']}\n")
        return ''.join(result)


class ImageProcessor(ContentProcessor):
    """图片处理器"""

    def __init__(self, formats: Dict):
        self.formats = formats

    def process(self, content: Dict) -> str:
        image_value = content['value']
        if isinstance(image_value, str):
            image_info = self.formats['imageblock'].get(image_value, {})
            if image_info:
                return f"![{image_info.get('alt', '')}]({image_info.get('url', '')})\n"
        return ""


class CodeExampleProcessor(ContentProcessor):
    """代码示例处理器"""

    def __init__(self, formats: Dict):
        self.formats = formats

    def process(self, content: Dict) -> str:
        code_value = content['value']
        if isinstance(code_value, str):
            code_info = self.formats['code_examples'].get(code_value, {})
            if code_info:
                return f"```{code_info.get('language', '')}\n{code_info.get('content', '')}\n```\n"
        return ""


class CodeBlockProcessor(ContentProcessor):
    """代码块处理器"""

    def __init__(self, formats: Dict):
        self.formats = formats

    def process(self, content: Dict) -> str:
        result = []
        code_blocks = content.get('code_blocks', [])
        if isinstance(code_blocks, list):
            for code_block in code_blocks:
                if isinstance(code_block, str):
                    block_info = self.formats['code_blocks'].get(code_block, {})
                    if block_info:
                        result.append(f"```{block_info.get('language', '')}\n{block_info.get('content', '')}\n```\n")
                else:
                    result.append(f"```{code_block.get('language', '')}\n{code_block.get('content', '')}\n```\n")
        return ''.join(result)


class MarkdownGenerator:
    """Markdown生成器，负责整体转换流程"""

    def __init__(self):
        self.processors = {
            'paragraph': None,  # 将在set_formats中设置
            'ulist': ListProcessor(),
            'imageblock': None,  # 将在set_formats中设置
            'code_examples': None,  # 将在set_formats中设置
            'code_blocks': None,  # 将在set_formats中设置
        }

    def set_formats(self, formats: Dict):
        """设置formats数据，初始化需要formats的处理器

        Args:
            formats: 包含各种格式信息的字典
        """
        self.processors['paragraph'] = ParagraphProcessor(formats)
        self.processors['imageblock'] = ImageProcessor(formats)
        self.processors['code_examples'] = CodeExampleProcessor(formats)
        self.processors['code_blocks'] = CodeBlockProcessor(formats)

    def process_section(self, section: Dict) -> List[str]:
        """处理单个章节

        Args:
            section: 章节内容字典

        Returns:
            List[str]: 处理后的markdown文本列表
        """
        md_content = []

        # 添加章节标题
        if section.get('title'):
            md_content.append(f"## {section['title']}\n")

        # 处理正文内容
        if 'body' in section:
            for item in section['body']:
                processor = self.processors.get(item['type'])
                if processor:
                    md_content.append(processor.process(item))

        # 递归处理子章节
        if 'sections' in section:
            for subsection in section['sections']:
                md_content.extend(self.process_section(subsection))

        return md_content

    def generate(self, data: Dict) -> str:
        """生成完整的markdown内容

        Args:
            data: 输入的JSON数据

        Returns:
            str: 生成的markdown文本
        """
        # 设置formats数据
        self.set_formats(data['formats'])

        # 添加YAML front matter
        md_content = [
            "---\n",
            f"title: \"{data['title']}\"\n",
            "weight: 1\n",
            "---\n\n"
        ]

        # 从主标题开始
        md_content.append(f"# {data['title']}\n")

        # 处理简介部分
        if 'introduction' in data['content']:
            intro = data['content']['introduction']
            if intro.get('title'):
                md_content.append(f"## {intro['title']}\n")
            for item in intro['body']:
                if item['type'] == 'paragraph':
                    md_content.append(self.processors['paragraph'].process(item))

        # 处理主要章节
        if 'sections' in data['content']:
            for section in data['content']['sections']:
                md_content.extend(self.process_section(section))

        return ''.join(md_content)


class JsonToMarkdownConverter:
    """JSON到Markdown的转换器，处理文件IO和转换流程"""

    def __init__(self, input_file: str, output_file: str):
        """初始化转换器

        Args:
            input_file: 输入JSON文件路径
            output_file: 输出Markdown文件路径
        """
        self.input_file = input_file
        self.output_file = output_file
        self.generator = MarkdownGenerator()

    def convert(self) -> None:
        """执行转换过程"""
        try:
            # 读取JSON文件
            print(f"Reading file: {self.input_file}")
            with open(self.input_file, 'r', encoding='utf-8') as f:
                data = json.load(f)

            # 生成markdown内容
            print("Generating markdown content...")
            markdown_content = self.generator.generate(data)

            # 确保输出目录存在
            os.makedirs(os.path.dirname(self.output_file), exist_ok=True)

            # 写入输出文件
            with open(self.output_file, 'w', encoding='utf-8') as f:
                f.write(markdown_content)
            print(f"Success: Markdown content has been generated and saved to {self.output_file}")

        except FileNotFoundError:
            print(f"Error: File not found: {self.input_file}")
            sys.exit(1)
        except json.JSONDecodeError as e:
            print(f"Error: Invalid JSON format in {self.input_file}: {str(e)}")
            sys.exit(1)
        except Exception as e:
            print(f"Error: An unexpected error occurred: {str(e)}")
            import traceback
            traceback.print_exc()
            sys.exit(1)


def main():
    """主函数：处理命令行参数并执行转换过程"""
    # 输入和输出文件路径
    json_file = 'output/spring-ai/1.0/json/concepts.json'
    output_file = 'output/spring-ai/1.0/content/concepts.md'

    # 检查输入文件是否存在
    if not os.path.exists(json_file):
        print(f"Error: Input file not found: {json_file}")
        sys.exit(1)

    # 创建转换器并执行转换
    converter = JsonToMarkdownConverter(json_file, output_file)
    converter.convert()


if __name__ == "__main__":
    main()
